package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pureut.storage.domain.Warehouse;
import com.pureut.storage.dto.InventoryInquiryDto;
import com.pureut.storage.dto.MaterialFinishedDto;
import com.pureut.storage.dto.MaterialRawDetailDto;
import com.pureut.storage.dto.UnitConversionDto;
import com.pureut.storage.mapper.WarehouseMapper;
import com.pureut.storage.mapper.WmsStockInfoMapper;
import com.pureut.storage.service.InventoryInquiryService;
import com.pureut.storage.util.UnitUtil;
import com.pureut.storage.vo.InventoryInquiryVo;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.domain.R;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.order.api.RemoteSupplierService;
import com.sale.system.api.RemoteCodingService;
import com.sale.system.api.RemoteInventoryInquiryService;
import com.sale.system.api.RemoteSysSupplierService;
import com.sale.system.api.RemoteUnitService;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysAuxiliaryUnitDateDetailResultDto;
import com.sale.system.api.domain.dto.SysMaterialCodingResultDto;
import com.sale.system.api.model.MaterialUnitDto;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: YSL
 * @Date: 2023/7/20 10:18
 * @Desc: 库存信息 业务层
 */
@Service
@RequiredArgsConstructor
public class InventoryInquiryServiceImpl implements InventoryInquiryService {

    /**
     * 库存表
     */
    private final WmsStockInfoMapper wmsStockInfoMapper;

    /**
     * 仓库表
     */
    private final WarehouseMapper warehouseMapper;

    /**
     * 物料类别 Dubbo
     */
    @DubboReference
    private final RemoteCodingService remoteCodingService;

    /**
     * 库存信息 Dubbo
     */
    @DubboReference
    private final RemoteInventoryInquiryService remoteInventoryInquiryService;

    @DubboReference
    RemoteSysSupplierService remoteSysSupplierService;

    @DubboReference
    RemoteUnitService remoteUnitService;

    @Resource
    UnitUtil unitUtil;

    /**
     * 查询库存汇总
     *
     * @param inventoryInquiryVo
     * @return
     */
    @Override
    public TableDataInfo<InventoryInquiryDto> selectInventoryInquiryList(InventoryInquiryVo inventoryInquiryVo, PageQuery pageQuery) throws Exception {
        InventoryInquiryVo warehouseById = this.getWarehouseById(inventoryInquiryVo);
        BeanUtils.copyProperties(warehouseById, inventoryInquiryVo);

        //根据字典查出库存类型
        List<SysDictData> materialType = CacheUtils.get(CacheNames.SYS_DICT, "wsi_material_type");
        Map<String, String> typeMap = materialType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //单位集合
        Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();

        // 获取库存汇总
        Page<InventoryInquiryDto> inventoryInquiryDtoPage = wmsStockInfoMapper.selectInventoryInquiryList(pageQuery.build(), inventoryInquiryVo);
        for (InventoryInquiryDto inventoryInquiryDto : inventoryInquiryDtoPage.getRecords()) {

            // 辅助信息
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + inventoryInquiryDto.getTenantId(), inventoryInquiryDto.getMaterialId());
            inventoryInquiryDto.setAuxiliaryProperties(statsArray);

            // 库存类型
            inventoryInquiryDto.setWsiMaterialTypeDict(typeMap.get(inventoryInquiryDto.getWsiMaterialType()));

            if (inventoryInquiryDto.getMaterialUnit() != null) {
                //单位
                inventoryInquiryDto.setUnitName(unitByCodeToMap.get(inventoryInquiryDto.getMaterialUnit()).getUnitName());
            }
            if (inventoryInquiryDto.getMaterialMoreUnit() != null) {
                //转换
                UnitConversionDto unitConversionDto = unitUtil.atWillunitConversion(inventoryInquiryDto.getMaterialUnit(), inventoryInquiryDto.getWsiMaterialCode(),
                    String.valueOf(inventoryInquiryDto.getUnitQuantity()), Long.valueOf(inventoryInquiryDto.getMaterialId()));
                if (unitConversionDto != null) {
                    inventoryInquiryDto.setUnitConversion(unitConversionDto.getMaterialMoreUnitNumber());
                }
            }

            // 通过类别id获取类别信息
//            if (inventoryInquiryDto.getWsiCategory() != null) {
//                R<SysMaterialCodingResultDto> sysMaterialCodingById = remoteCodingService.getSysMaterialCodingById(Long.valueOf(inventoryInquiryDto.getWsiCategory()));
//                SysMaterialCodingResultDto codingData = sysMaterialCodingById.getData();
//                // 类别名称
//                inventoryInquiryDto.setWsiCategoryName(codingData.getCodingRules());
//            }
//            // 判断单个单位是否为空
//            if (inventoryInquiryDto.getMaterialUnit() != null) {
//                // 获取单计量单位
//                MaterialUnitDto byAuxiliaryData = remoteInventoryInquiryService.getByAuxiliaryData(Long.valueOf(inventoryInquiryDto.getMaterialUnit()));
//                if (byAuxiliaryData != null) {
//                    // 单计量单位名称
//                    inventoryInquiryDto.setUnitName(byAuxiliaryData.getUnitName());
//                }
//            } else {
//                SysAuxiliaryUnitDateDetailResultDto materialUnitById = remoteInventoryInquiryService.getMaterialUnitById(null,Long.valueOf(inventoryInquiryDto.getMaterialId()));
//                // 多计量单位名称
//                inventoryInquiryDto.setAuxiliaryUnitName(materialUnitById.getMoreUnitName());
//                // 获取逗号前的基础单位
//                int str = materialUnitById.getAuxiliaryUnitName().indexOf(',');
//                String substring = materialUnitById.getAuxiliaryUnitName().substring(0, str);
//                // 基本单位
//                inventoryInquiryDto.setUnitName(substring);
//                // 辅助单位
//                inventoryInquiryDto.setAuxiliaryUnit(materialUnitById.getAuxiliaryUnitName());
//
//                // 判断单位数量是否为空
//                if (inventoryInquiryDto.getUnitQuantity() != null) {
//                    if (inventoryInquiryDto.getUnitQuantity()!=null) {
//                        // 获取多单位换算
//                        MaterialUnitDto materialUnitDto = remoteInventoryInquiryService.selectAtWillMaterialUnitList(Long.valueOf(inventoryInquiryDto.getMaterialId()), Long.valueOf(inventoryInquiryDto.getUnitQuantity()));
//                        inventoryInquiryDto.setAuxiliaryUnitName(materialUnitDto.getUnitName());
//                    }
//                } else {
//                    inventoryInquiryDto.setAuxiliaryUnitName("");
//                }
//            }
        }

        return TableDataInfo.build(inventoryInquiryDtoPage);
    }

    /**
     * 查询原料明细
     *
     * @param inventoryInquiryVo
     * @return
     */
    @Override
    public TableDataInfo<MaterialRawDetailDto> selectMaterialRawDetail(InventoryInquiryVo inventoryInquiryVo, PageQuery pageQuery) throws Exception {
        InventoryInquiryVo warehouseById = this.getWarehouseById(inventoryInquiryVo);
        BeanUtils.copyProperties(warehouseById, inventoryInquiryVo);

        //根据字典查出库存类型
        List<SysDictData> materialType = CacheUtils.get(CacheNames.SYS_DICT, "wsi_material_type");
        Map<String, String> typeMap = materialType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //根据字典查出库存状态
        List<SysDictData> wmsStockStatus = CacheUtils.get(CacheNames.SYS_DICT, "wms_stock_info_status");
        Map<String, String> wmsStockMap = wmsStockStatus.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        // 原料明细List
        Page<MaterialRawDetailDto> materialRawDetailDtoPage = wmsStockInfoMapper.selectMaterialRawDetail(pageQuery.build(), inventoryInquiryVo);
        //供应商
        Map<String, String> supplierMap = remoteSysSupplierService.getOpenSupplierFinance();
        for (MaterialRawDetailDto materialRawDetailDto : materialRawDetailDtoPage.getRecords()) {

            //供应商
            materialRawDetailDto.setSupplierName(supplierMap.get(materialRawDetailDto.getWsiSupplierCode()));

            // 辅助信息
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + materialRawDetailDto.getTenantId(), materialRawDetailDto.getMaterialId());
            materialRawDetailDto.setAuxiliaryProperties(statsArray);

            // 库存类型
            materialRawDetailDto.setWsiMaterialTypeDict(typeMap.get(materialRawDetailDto.getWsiMaterialType()));

            // 库存状态
            materialRawDetailDto.setWsiMaterialStatusDict(wmsStockMap.get(materialRawDetailDto.getWsiMaterialStatus()));

            // 通过类别id获取类别信息
            R<SysMaterialCodingResultDto> sysMaterialCodingById = remoteCodingService.getSysMaterialCodingById(Long.valueOf(materialRawDetailDto.getWsiCategory()));
            SysMaterialCodingResultDto codingData = sysMaterialCodingById.getData();
            // 类别名称
            materialRawDetailDto.setWsiCategoryName(codingData.getCodingRules());

            // 判断单个单位是否为空
            if (materialRawDetailDto.getMaterialUnit() != null) {
                // 获取单计量单位
                MaterialUnitDto byAuxiliaryData = remoteInventoryInquiryService.getByAuxiliaryData(Long.valueOf(materialRawDetailDto.getMaterialUnit()));
                // 单计量单位名称
                materialRawDetailDto.setUnitName(byAuxiliaryData.getUnitName());
            } else {
                SysAuxiliaryUnitDateDetailResultDto materialUnitById = remoteInventoryInquiryService.getMaterialUnitById(Long.valueOf(materialRawDetailDto.getMaterialMoreUnit()), Long.valueOf(materialRawDetailDto.getMaterialId()));
                // 多计量单位名称
                materialRawDetailDto.setAuxiliaryUnitName(materialUnitById.getAuxiliaryUnitName());
                // 获取逗号前的基础单位
                int str = materialUnitById.getAuxiliaryUnitName().indexOf(',');
                String substring = materialUnitById.getAuxiliaryUnitName().substring(0, str);
                // 基本单位
                materialRawDetailDto.setUnitName(substring);
                // 辅助单位
                materialRawDetailDto.setAuxiliaryUnit(materialUnitById.getAuxiliaryUnitName());
                if (materialRawDetailDto.getAuxiliaryUnit() != null) {
                    if (materialRawDetailDto.getUnitQuantity() != null) {
                        // 获取多单位换算
                        MaterialUnitDto materialUnitDto = remoteInventoryInquiryService.selectAtWillMaterialUnitList(Long.valueOf(materialRawDetailDto.getMaterialId()), Long.valueOf(materialRawDetailDto.getUnitQuantity()));
                        if (materialUnitDto != null) {
                            materialRawDetailDto.setAuxiliaryUnitName(materialUnitDto.getUnitName());
                        }
                    }
                } else {
                    materialRawDetailDto.setAuxiliaryUnitName("");
                }

            }
        }
        return TableDataInfo.build(materialRawDetailDtoPage);
    }

    /**
     * 查询成品明细
     *
     * @param inventoryInquiryVo
     * @return
     */
    @Override
    public TableDataInfo<MaterialFinishedDto> selectMaterialFinishedDetail(InventoryInquiryVo inventoryInquiryVo, PageQuery pageQuery) throws Exception {
        InventoryInquiryVo warehouseById = this.getWarehouseById(inventoryInquiryVo);
        BeanUtils.copyProperties(warehouseById, inventoryInquiryVo);

        //根据字典查出库存类型
        List<SysDictData> materialType = CacheUtils.get(CacheNames.SYS_DICT, "wsi_material_type");
        Map<String, String> typeMap = materialType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //根据字典查出库存状态
        List<SysDictData> wmsStockStatus = CacheUtils.get(CacheNames.SYS_DICT, "wms_stock_info_status");
        Map<String, String> wmsStockMap = wmsStockStatus.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        // 成品List
        Page<MaterialFinishedDto> materialFinishedDtoPage = wmsStockInfoMapper.selectMaterialFinishedDetail(pageQuery.build(), inventoryInquiryVo);
        for (MaterialFinishedDto materialFinishedDto : materialFinishedDtoPage.getRecords()) {

            // 辅助信息
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + materialFinishedDto.getTenantId(), materialFinishedDto.getMaterialId());
            materialFinishedDto.setAuxiliaryProperties(statsArray);

            // 库存类型
            materialFinishedDto.setWsiMaterialTypeDict(typeMap.get(materialFinishedDto.getWsiMaterialType()));
            // 库存状态
            materialFinishedDto.setWsiMaterialStatusDict(wmsStockMap.get(materialFinishedDto.getWsiMaterialStatus()));

            // 通过类别id获取类别信息
            R<SysMaterialCodingResultDto> sysMaterialCodingById = remoteCodingService.getSysMaterialCodingById(Long.valueOf(materialFinishedDto.getWsiCategory()));
            SysMaterialCodingResultDto codingData = sysMaterialCodingById.getData();
            // 类别名称
            materialFinishedDto.setWsiCategoryName(codingData.getCodingRules());

            // 判断单个单位是否为空
            if (materialFinishedDto.getMaterialUnit() != null) {
                // 获取单计量单位
                MaterialUnitDto byAuxiliaryData = remoteInventoryInquiryService.getByAuxiliaryData(Long.valueOf(materialFinishedDto.getMaterialUnit()));
                // 单计量单位名称
                materialFinishedDto.setUnitName(byAuxiliaryData.getUnitName());
            } else {
                SysAuxiliaryUnitDateDetailResultDto materialUnitById = remoteInventoryInquiryService.getMaterialUnitById(Long.valueOf(materialFinishedDto.getMaterialMoreUnit()), Long.valueOf(materialFinishedDto.getMaterialId()));
                // 多计量单位名称
                materialFinishedDto.setAuxiliaryUnitName(materialUnitById.getAuxiliaryUnitName());
                // 获取逗号前的基础单位
                int str = materialUnitById.getAuxiliaryUnitName().indexOf(',');
                String substring = materialUnitById.getAuxiliaryUnitName().substring(0, str);
                // 基本单位
                materialFinishedDto.setUnitName(substring);
                // 辅助单位
                materialFinishedDto.setAuxiliaryUnit(materialUnitById.getAuxiliaryUnitName());
                if (materialFinishedDto.getAuxiliaryUnit() != null) {
                    if (materialFinishedDto.getUnitQuantity() != null) {
                        // 获取多单位换算
                        MaterialUnitDto materialUnitDto = remoteInventoryInquiryService.selectMaterialUnitList(Long.valueOf(materialFinishedDto.getMaterialMoreUnit()), Long.valueOf(materialFinishedDto.getUnitQuantity()));
                        materialFinishedDto.setAuxiliaryUnitName(materialUnitDto.getUnitName());
                    }
                } else {
                    materialFinishedDto.setAuxiliaryUnitName("");
                }

            }
        }
        return TableDataInfo.build(materialFinishedDtoPage);
    }

    /**
     * 根据模糊查询获取仓库id
     *
     * @param inventoryInquiryVo
     * @return
     */
    @Override
    public InventoryInquiryVo getWarehouseById(InventoryInquiryVo inventoryInquiryVo) {
        if (inventoryInquiryVo.getWarehouseIds() != null) {
            // 获取仓库信息
            Warehouse warehouse = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, inventoryInquiryVo.getWarehouseIds()));
            // 仓库类型(1、仓库,2、库区,3、库位)
            if (warehouse.getWarehouseType() == 1) {
                inventoryInquiryVo.setWsiWarehourse(String.valueOf(warehouse.getId()));
            } else if (warehouse.getWarehouseType() == 2) {
                inventoryInquiryVo.setWsiReservoirArea(String.valueOf(warehouse.getId()));
            } else if (warehouse.getWarehouseType() == 3) {
                inventoryInquiryVo.setWsiStorageLoaction(String.valueOf(warehouse.getId()));
            }
        }
        return inventoryInquiryVo;
    }
}
